package view;

import java.awt.Choice;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;

import Serveur.Serialization;

import Both.Trajet;
import Both.Transport;
import Both.Ville;
import controleur.*;

/**
 * @author Blond Jeremie
 * 
 *         Description:
 * 
 *         Cette class permet de lister les trajets en fonction des villes
 *         d'arrivé et de depart (en direct ou non) Une fois que l'on a cliqué
 *         sur l'un des trajets ces informations sont ecrites a droite de la on
 *         a le choix d'effectuer une reservation sur ce trajet L'admin lui peut
 *         modifier ou ajouter un nouveau trajet.
 * 
 */
public class Fenetre1 extends JFrame {

    // declaration des composants que l'on peut avoir a modifier
    private ToutFenetre tout;
    private JLabel nbrePlaceDispLabel;
    private JLabel nbrePlaceDisp;
    private JLabel VilleDepLabel;
    private JLabel VilleDepChoisi;
    private JLabel VilleDarLabel;
    private JLabel VilleDarChoisi;
    private JLabel DateDepLabel;
    private JLabel DateDepChoisi;
    private JLabel DateDarLabel;
    private JLabel DateDarChoisi;
    private JLabel TranspoLabel;
    private JLabel Transpo;
    private JLabel infoLabel;
    private JLabel infoLabel2;
    private JButton Ajouter;
    private JButton Modifier;
    private JButton Reserver;
    private JButton Recherche;
    private Choice c;
    private Choice c2;
    private int Type;
    private boolean direct;
    private JSeparator separator;

    private JList maJList;

    private JScrollPane scroll;

    private JPanel p1;

    private JLabel choix;
    private JLabel choix2;
    private JLabel choix3;

    private JCheckBox myCheckBox;

    private Trajet trajetSelection;
    private ArrayList<Trajet> listTrajetSelection;
    private ArrayList<Trajet> listTrajet;
    private ArrayList<Ville> listVille;

    public Fenetre1(ArrayList<Ville> listVille, ToutFenetre tout) {
        super("Systeme de reservation");
        this.listTrajet = new ArrayList<Trajet>();
        this.listTrajetSelection = new ArrayList<Trajet>();
        this.listVille = listVille;
        this.tout = tout;

        addWindowListener(new closeListener(tout));

        /* 1- Initialisation du container. */
        this.setLayout(new GridBagLayout());

        /* 2- Création et initialisation d'une série de composants. */

        infoLabel = new JLabel("Voici la liste des trajets : ");
        infoLabel2 = new JLabel("Selectionner ville de depart et d'arrivé : ");
        nbrePlaceDispLabel = new JLabel("Nbre place disponible :");
        nbrePlaceDisp = new JLabel("");
        nbrePlaceDisp.setPreferredSize(new Dimension(180, 20));
        VilleDepLabel = new JLabel("Ville de depat:");
        VilleDepChoisi = new JLabel("");
        VilleDarLabel = new JLabel("Ville d'arrivé :");
        VilleDarChoisi = new JLabel("");
        DateDepLabel = new JLabel("Date de depart:");
        DateDepChoisi = new JLabel("");
        DateDarLabel = new JLabel("Date d'arrivé:");
        DateDarChoisi = new JLabel("");
        TranspoLabel = new JLabel("Type de Transport :");
        Transpo = new JLabel();
        myCheckBox = new JCheckBox("direct", true);

        c = new Choice();
        c2 = new Choice();
        c.add("--");
        c2.add("--");
        Iterator<Ville> monIterateur = listVille.iterator();
        Ville temp;
        while (monIterateur.hasNext()) {
            temp = monIterateur.next();
            c.add(temp.getVille());
            c2.add(temp.getVille());
        }

        c.select("--");
        c2.select("--");

        p1 = new JPanel();

        Ajouter = new JButton("Ajouter");
        Ajouter.addActionListener(new ActionAppelFenetre2(tout, 2));

        Modifier = new JButton("Modifier");
        Modifier.addActionListener(new ActionAppelFenetre2(tout, 1));

        Reserver = new JButton("Reserver");
        Reserver.addActionListener(new ActionReserver(tout));

        Recherche = new JButton("Recherche");
        Recherche.addActionListener(new ActionRecherche(tout));

        choix = new JLabel("Voulez vous effectuer une reservation ");
        choix2 = new JLabel("sur ce trajet?");
        choix3 = new JLabel("Voulez vous \"Ajouter\" un nouveau trajet?");

        labelVisble(false);
        modAdmin(false);
        modClient(false);
        ChampVisible(false);

        separator = new JSeparator();

        p1.setPreferredSize(new Dimension(200, 200));

        /*
         * Ajout de ces composants en spécifiant les contraintes de type
         * GridBagConstraints.
         */
        GridBagConstraints gbc = new GridBagConstraints();

        /* a- ajout du label dinfo2. */
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(0, 5, 0, 0);
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        this.add(infoLabel2, gbc);
        // -----------------------------------------------------------------------------------------

        /* a-1- ajout du component choice1 . */
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.insets = new Insets(0, 5, 0, 0);
        gbc.anchor = GridBagConstraints.BASELINE;
        this.add(c, gbc);
        // -----------------------------------------------------------------------------------------

        /* a-2 - ajout du component choice2 */
        gbc.gridx = 2;
        gbc.gridy = 0;
        gbc.insets = new Insets(0, 5, 0, 0);
        gbc.anchor = GridBagConstraints.BASELINE;
        this.add(c2, gbc);
        // -----------------------------------------------------------------------------------------

        /* a-2 - ajout d'une checkbox */
        gbc.gridx = 3;
        gbc.gridy = 0;
        gbc.insets = new Insets(0, 5, 0, 0);
        gbc.anchor = GridBagConstraints.BASELINE;
        this.add(myCheckBox, gbc);
        // -----------------------------------------------------------------------------------------

        /* a- ajout du label dinfo. */
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.insets = new Insets(0, 5, 0, 0);
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        this.add(infoLabel, gbc);
        // -----------------------------------------------------------------------------------------

        /* a-3 - ajout du bouton recherche. */
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.insets = new Insets(0, 5, 0, 0);
        gbc.anchor = GridBagConstraints.BASELINE;
        this.add(Recherche, gbc);
        // -----------------------------------------------------------------------------------------

        /*
         * b- ajout de la zone pour la scrollbar de tout les trajet. Nous avons
         * utilisé un panel pour cela.
         */
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.gridwidth = 1;
        gbc.gridheight = 8;
        /*
         * Ici, nous ne voulons surement pas que le composant s'aligne sur la
         * ligne de base. Nous allons donc utiliser la constance LINE_START.
         */
        gbc.anchor = GridBagConstraints.LINE_START;
        gbc.insets = new Insets(10, 5, 0, 0);
        this.add(p1, gbc);
        // -----------------------------------------------------------------------------------------

        /* c- étiquette du nombre de palce dispo */
        gbc.gridx = 1;
        gbc.gridy = 2;
        gbc.gridwidth = gbc.gridheight = 1;
        /*
         * L'étiquette avec le nom sera alignée sur la ligne de base avec le
         * champ de saisie pour le nom.
         */
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        gbc.insets = new Insets(7, 5, 0, 0);
        this.add(nbrePlaceDispLabel, gbc);
        // -----------------------------------------------------------------------------------------

        /* d- le champs du nombre de place dispo */
        gbc.gridx = 2;
        gbc.gridy = 2;
        gbc.gridwidth = GridBagConstraints.REMAINDER; // dernier composant de la
                                                      // ligne.
        gbc.fill = GridBagConstraints.HORIZONTAL; // étalons le sur l'espace
                                                  // disponible.
        gbc.insets = new Insets(3, 5, 0, 5); // laissons tout de même une marge
                                             // à droite.
        gbc.anchor = GridBagConstraints.BASELINE; // alignons le sur la même
                                                  // ligne de base que son
                                                  // étiquette.
        this.add(nbrePlaceDisp, gbc);
        // -----------------------------------------------------------------------------------------

        /* e- l'étiquette de la ville de depart */
        gbc.gridx = gbc.gridwidth = gbc.gridheight = 1;
        gbc.gridy = 3;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        gbc.insets = new Insets(0, 5, 0, 0);
        this.add(VilleDepLabel, gbc);
        // -----------------------------------------------------------------------------------------

        /* f- le champs de la ville de depart */
        gbc.gridx = 2;
        gbc.gridy = 3;
        gbc.gridwidth = GridBagConstraints.REMAINDER; // dernier composant de la
                                                      // ligne.
        gbc.fill = GridBagConstraints.HORIZONTAL; // étalons le sur l'espace
                                                  // disponible.
        gbc.insets = new Insets(3, 5, 0, 5); // laissons tout de même une marge
                                             // à droite.
        gbc.anchor = GridBagConstraints.BASELINE; // alignons le sur la même
                                                  // ligne de base que son
                                                  // étiquette.
        this.add(VilleDepChoisi, gbc);
        // -----------------------------------------------------------------------------------------

        /* g- l'étiquette de la ville darrive */
        gbc.gridx = 1;
        gbc.gridwidth = gbc.gridheight = 1;
        gbc.gridy = 4;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        gbc.insets = new Insets(0, 5, 0, 0);
        this.add(VilleDarLabel, gbc);
        // -----------------------------------------------------------------------------------------

        /* h- le champs de la ville darrive */
        gbc.gridx = 2;
        gbc.gridy = 4;
        gbc.gridwidth = GridBagConstraints.REMAINDER; // dernier composant de la
                                                      // ligne.
        gbc.fill = GridBagConstraints.HORIZONTAL; // étalons le sur l'espace
                                                  // disponible.
        gbc.insets = new Insets(3, 5, 0, 5); // laissons tout de même une marge
                                             // à droite.
        gbc.anchor = GridBagConstraints.BASELINE; // alignons le sur la même
                                                  // ligne de base que son
                                                  // étiquette.
        this.add(VilleDarChoisi, gbc);
        // -----------------------------------------------------------------------------------------

        /* i- l'étiquette de la date depart */
        gbc.gridx = 1;
        gbc.gridwidth = gbc.gridheight = 1;
        gbc.gridy = 5;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        gbc.insets = new Insets(0, 5, 0, 0);
        this.add(DateDepLabel, gbc);
        // -----------------------------------------------------------------------------------------

        /* j- le champs de la date de depart */
        gbc.gridx = 2;
        gbc.gridy = 5;
        gbc.gridwidth = GridBagConstraints.REMAINDER; // dernier composant de la
                                                      // ligne.
        gbc.fill = GridBagConstraints.HORIZONTAL; // étalons le sur l'espace
                                                  // disponible.
        gbc.insets = new Insets(3, 5, 0, 5); // laissons tout de même une marge
                                             // à droite.
        gbc.anchor = GridBagConstraints.BASELINE; // alignons le sur la même
                                                  // ligne de base que son
                                                  // étiquette.
        this.add(DateDepChoisi, gbc);
        // -----------------------------------------------------------------------------------------

        /* k- l'étiquette de la date darrive */
        gbc.gridx = 1;
        gbc.gridwidth = gbc.gridheight = 1;
        gbc.gridy = 6;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        gbc.insets = new Insets(0, 5, 0, 0);
        this.add(DateDarLabel, gbc);
        // -----------------------------------------------------------------------------------------

        /* l- le champs de la date darrive. */
        gbc.gridx = 2;
        gbc.gridy = 6;
        gbc.gridwidth = GridBagConstraints.REMAINDER; // dernier composant de la
                                                      // ligne.
        gbc.fill = GridBagConstraints.HORIZONTAL; // étalons le sur l'espace
                                                  // disponible.
        gbc.insets = new Insets(3, 5, 0, 5); // laissons tout de même une marge
                                             // à droite.
        gbc.anchor = GridBagConstraints.BASELINE; // alignons le sur la même
                                                  // ligne de base que son
                                                  // étiquette.
        this.add(DateDarChoisi, gbc);
        // -----------------------------------------------------------------------------------------

        /* k- l'étiquette du transpo */
        gbc.gridx = 1;
        gbc.gridwidth = gbc.gridheight = 1;
        gbc.gridy = 7;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        gbc.insets = new Insets(0, 5, 0, 0);
        this.add(TranspoLabel, gbc);
        // --------------------------------------------------------------------------------------------------

        // l- le champs du transpo
        gbc.gridx = 2;
        gbc.gridy = 7;
        gbc.gridwidth = GridBagConstraints.REMAINDER; // dernier composant de la
                                                      // ligne.
        gbc.fill = GridBagConstraints.HORIZONTAL; // étalons le sur l'espace
                                                  // disponible.
        gbc.insets = new Insets(3, 5, 0, 5); // laissons tout de même une marge
                                             // à droite.
        gbc.anchor = GridBagConstraints.BASELINE; // alignons le sur la même
                                                  // ligne de base que son
                                                  // étiquette.
        this.add(Transpo, gbc);
        // --------------------------------------------------------------------------------------------------

        /* o- l'étiquette pour choix. */
        gbc.gridx = 1;
        gbc.gridwidth = 2;
        gbc.gridheight = 1;
        gbc.gridy = 8;
        gbc.fill = GridBagConstraints.HORIZONTAL; // étalons le sur l'espace
                                                  // disponible.
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        gbc.insets = new Insets(20, 5, 0, 0);
        this.add(choix, gbc);
        // -----------------------------------------------------------------------------------------

        /* p- l'étiquette pour choix2. */
        gbc.gridx = 1;
        gbc.gridwidth = 2;
        gbc.gridheight = 1;
        gbc.gridy = 9;
        gbc.fill = GridBagConstraints.HORIZONTAL; // étalons le sur l'espace
                                                  // disponible.
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        gbc.insets = new Insets(0, 5, 0, 0);
        this.add(choix2, gbc);
        // -----------------------------------------------------------------------------------------

        /* q- le bouton Reserver. */
        gbc.gridx = 1;
        gbc.gridwidth = gbc.gridheight = 1;
        gbc.gridy = 10;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        gbc.insets = new Insets(0, 5, 0, 0);
        this.add(Reserver, gbc);
        // -----------------------------------------------------------------------------------------

        /* r- le bouton Modifier. */
        gbc.gridx = 2;
        gbc.gridy = 10;
        gbc.gridwidth = GridBagConstraints.REMAINDER; // dernier composant de la
                                                      // ligne.
        gbc.fill = GridBagConstraints.NONE; // étalons le sur l'espace
                                            // disponible.
        gbc.insets = new Insets(3, 5, 0, 5); // laissons tout de même une marge
                                             // à droite.
        gbc.anchor = GridBagConstraints.BASELINE; // alignons le sur la même
                                                  // ligne de base que son
                                                  // étiquette.
        this.add(Modifier, gbc);
        // -----------------------------------------------------------------------------------------

        /* s- Un séparateur. */
        gbc.gridy = 11;
        gbc.gridx = 0;
        gbc.gridwidth = 3;
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(5, 5, 0, 5);
        this.add(separator, gbc);
        // -----------------------------------------------------------------------------------------

        /* t- etiquette choix3 */
        gbc.gridx = 0;
        gbc.gridy = 12;
        gbc.gridwidth = 3;
        gbc.fill = GridBagConstraints.NONE; // étalons le sur l'espace
                                            // disponible.
        gbc.anchor = GridBagConstraints.BASELINE_LEADING;
        gbc.insets = new Insets(20, 5, 0, 0);
        this.add(choix3, gbc);
        // -----------------------------------------------------------------------------------------

        /* u- le buton Ajouter. */
        gbc.gridx = 0;
        gbc.gridy = 13;
        gbc.gridheight = 1;
        gbc.gridwidth = GridBagConstraints.REMAINDER; // dernier composant de la
                                                      // ligne.
        gbc.fill = GridBagConstraints.NONE; // étalons le sur l'espace
                                            // disponible.
        gbc.insets = new Insets(15, 5, 0, 5); // laissons tout de même une marge
                                              // à droite.
        gbc.anchor = GridBagConstraints.BASELINE; // alignons le sur la même
                                                  // ligne de base que son
                                                  // étiquette.
        this.add(Ajouter, gbc);
        // -----------------------------------------------------------------------------------------

        this.setMinimumSize(new Dimension(700, 400));
        this.setLocationRelativeTo(null);
    }

    public JList getJList() {
        // rend la JList de trajet
        return maJList;
    }

    public void modClient(boolean b) {
        // rend visible ou non certain champ d'information
        Reserver.setVisible(b);
        choix.setVisible(b);
        choix2.setVisible(b);
        if (!b) {
            nbrePlaceDisp.setText("");
            VilleDepChoisi.setText("");
            VilleDarChoisi.setText("");
            DateDepChoisi.setText("");
            DateDarChoisi.setText("");
            Transpo.setText("");
            choix.setText("Voulez vous effectuer une reservation ");
            choix2.setText("sur ce trajet?");
        }
    }

    public void labelVisble(boolean b) {
        // rend visible ou non certain champ d'information
        nbrePlaceDispLabel.setVisible(b);
        VilleDepLabel.setVisible(b);
        VilleDarLabel.setVisible(b);
        DateDepLabel.setVisible(b);
        DateDarLabel.setVisible(b);
        TranspoLabel.setVisible(b);

    }

    public void ChampVisible(boolean b) {
        infoLabel.setVisible(b);
        p1.setVisible(b);
    }

    public void setCheckBoxInvisible() {
        myCheckBox.setVisible(false);
    }

    public void modAdmin(boolean b) {
        if (b) {
            choix.setText("Voulez effectuer une modification pour");
            choix2.setText("ce Trajet");
        }
        Reserver.setVisible(!b);
        Modifier.setVisible(b);
        Ajouter.setVisible(b);
        choix3.setVisible(b);
    }

    public String getVilleDepart() {
        return c.getSelectedItem();
    }

    public String getVilleDarrive() {
        return c2.getSelectedItem();
    }

    public void afficheTajet(Trajet t) {
        // affiche le trajet sur la droite de la fenetre
        VilleDepChoisi.setText(t.getVilleDepart().getVille());
        VilleDarChoisi.setText(t.getVilleArrive().getVille());
        DateDepChoisi.setText(t.getFormatedDate(t.getDateDepart().getTime()));
        DateDarChoisi.setText(t.getFormatedDate(t.getDateArrive().getTime()));
        nbrePlaceDisp.setText("" + t.getNbPlaceDispo());
        Transpo.setText(t.getTransport().getType().getTransportString());
        // on met a jour le trajet selectionné
        trajetSelection = t;
        removeMaList();
        listTrajetSelection.add(t);
    }

    public void afficheTajetIndirect(ArrayList<Trajet> listTrajet) {
        // affiche le Trajet sur la droite de la fenetre
        String nbrePlaceString = "";
        String TranspoString = "";
        VilleDepChoisi.setText(listTrajet.get(0).getVilleDepart().getVille());
        VilleDarChoisi.setText(listTrajet.get(listTrajet.size() - 1)
                .getVilleArrive().getVille());
        DateDepChoisi.setText(listTrajet.get(0).getDateDepart()
                .getGregorianChange().toString());
        DateDarChoisi.setText(listTrajet.get(listTrajet.size() - 1)
                .getDateArrive().getGregorianChange().toString());
        for (int i = 0; i < listTrajet.size(); i++) {
            nbrePlaceString = nbrePlaceString + "/"
                    + listTrajet.get(i).getNbPlaceDispo();
            TranspoString = TranspoString
                    + "/"
                    + listTrajet.get(i).getTransport().getType()
                            .getTransportString();
        }
        nbrePlaceDisp.setText(nbrePlaceString);
        Transpo.setText(TranspoString);
        // on met a jour le Trajet selectionné
        listTrajetSelection = listTrajet;
    }

    public Trajet getTrajetSelection() {
        // recupere le trajet selectionné
        return trajetSelection;
    }

    public ArrayList<Trajet> getLisTrajetSelection() {
        // recupere le contact selectionné
        return listTrajetSelection;
    }

    public void setType(int n) {
        Type = n;
    }

    public int getType() {
        return Type;
    }

    public boolean getCheckbox() {
        return myCheckBox.isSelected();
    }

    public void setDirect(boolean b) {
        direct = b;
    }

    public boolean getDirect() {
        return direct;
    }

    public void setTrajet(JList nouvelleJListTrajet,
            ArrayList<Trajet> listTrajet) {
        // permet d'afficher la liste des contacts passé en paramettre
        this.listTrajet = listTrajet;
        p1.removeAll();
        maJList = nouvelleJListTrajet;
        maJList.addListSelectionListener(new ListSelection(listTrajet, tout));
        scroll = new JScrollPane(maJList);
        p1.add(scroll);
        ChampVisible(true);
        labelVisble(false);
        modClient(false);
        this.repaint();
    }

    public void removeMaList() {
        while (!listTrajetSelection.isEmpty()) {
            listTrajetSelection.remove(0);
        }
    }
}

class closeListener extends WindowAdapter {
    // pour fermer la fenetre avec le X de la decoration
    ToutFenetre tout;

    public closeListener(ToutFenetre tout) {
        this.tout = tout;
    }

    public void windowClosing(WindowEvent e) {
        tout.monServeur.closeServeur();
        System.exit(0);
    }

}